var G = {};

G.createFnQueue = function (shift) {
    var _list = [];

    return {
        add: function (fn) {
            if ($.isFunction(fn))
                _list.push(fn);
        },

        exec: function (o) {
            if (shift !== false) {
                while (_list.length > 0) {
                    _list.shift()(o);
                }
            }
            else {
                for (var i = 0, len = _list.length; i < len; i++) {
                    if (_list[i](o) === false) {
                        return false; // 类似事件的回调函数
                    }
                }
            }
        },

        clear: function () {
            _list.length = 0;
        }
    };
};

G.app = {}; // 应用
G.logic = {}; // 业务公共逻辑相关
G.ui = {}; // 界面相关
G.util = {}; // 工具相关

//jquery升级到1.9版本以后  $.browser.msie就会报错,用以下代码解决
jQuery.browser = {};
(function () {
    jQuery.browser.msie = false;
    jQuery.browser.version = 0;
    if (navigator.userAgent.match(/MSIE ([0-9]+)./)) {
        jQuery.browser.msie = true;
        jQuery.browser.version = RegExp.$1;
    }
})();


if ($.browser.msie && parseInt($.browser.version, 10) < 7) {
    try {
        document.execCommand("BackgroundImageCache", false, true);
    } catch (e) {
    }
}
/*
 * Cookie 相关操作
 */
G.util.cookie = {
    get: function (name) {
        var r = new RegExp("(^|;|\\s+)" + name + "=([^;]*)(;|$)");
        var m = document.cookie.match(r);
        return (!m ? "" : unescape(m[2]));
    },

    add: function (name, v, path, expire, domain) {
        var s = name + "=" + escape(v)
            + "; path=" + ( path || '/' ) // 默认根目录
            + (domain ? ("; domain=" + domain) : '');
        if (expire > 0) {
            var d = new Date();
            d.setTime(d.getTime() + expire * 1000);
            s += ";expires=" + d.toGMTString();
        }
        document.cookie = s;
    },

    del: function (name, domain) {
        document.cookie = name + "=;path=/;" + (domain ? ("domain=" + domain + ";") : '') + "expires=" + (new Date(0)).toGMTString();
    }
};

/*
 * token 相关操作
 */
G.util.token = {
    //给连接加上token
    addToken: function (url, type) {
        //type标识请求的方式,jq标识jquery，lk标识普通链接,fr标识form表单,ow打开新窗口
        var token = this.getToken();
        //只支持http和https协议，当url中无协议头的时候，应该检查当前页面的协议头
        if (url == "" || (url.indexOf("://") < 0 ? location.href : url).indexOf("http") != 0) {
            return url;
        }
        if (url.indexOf("#") != -1) {
            var f1 = url.match(/\?.+\#/);
            if (f1) {
                var t = f1[0].split("#"), newPara = [t[0], "&g_tk=", token, "&g_ty=", type, "#", t[1]].join("");
                return url.replace(f1[0], newPara);
            } else {
                var t = url.split("#");
                return [t[0], "?g_tk=", token, "&g_ty=", type, "#", t[1]].join("");
            }
        }
        //无论如何都把g_ty带上，用户服务器端判断请求的类型
        return token == "" ? (url + (url.indexOf("?") != -1 ? "&" : "?") + "g_ty=" + type) : (url + (url.indexOf("?") != -1 ? "&" : "?") + "g_tk=" + token + "&g_ty=" + type);
    },
    //获取转换后的token
    getToken: function () {
        var skey = G.util.cookie.get("skey"),
            token = skey == null ? "" : this.time33(skey);
        return token;
    },
    //skey转token
    time33: function (str) {
        //哈希time33算法
        for (var i = 0, len = str.length, hash = 5381; i < len; ++i) {
            hash += (hash << 5) + str.charAt(i).charCodeAt();
        }
        ;
        return hash & 0x7fffffff;
    }
}


/*新增token处理*/
G.util.getACSRFToken = function () {
    if (G.util.cookie.get("g_tk")) {
        return G.util._DJB(G.util.cookie.get("g_tk"))
    } else {
        return false;
    }
    ;
}

G.util._DJB = function (str) {
    var hash = 5381;
    for (var i = 0, len = str.length; i < len; ++i) {
        hash += (hash << 5) + str.charAt(i).charCodeAt();
    }
    return hash & 0x7fffffff;
}

G.util.token_post = function (options) {
    var opt = jQuery.extend({
        "type": "POST",
        "cache": false,
        "dataType": "json",
        "timeout": 8000
    }, options);

    //加上token值
    if (G.util.getACSRFToken()) {
        opt.url = options.url + "&token=" + G.util.getACSRFToken();
    }

    //调用jQuery AJAX
    jQuery.ajax(opt);
};

G.util.parse = {
    url: function () {

        var _myDecode = function (q) {
            var q = (q + '').replace(/(&amp;|\?)/g, "&").split('&');
            var p = {};
            var c = q.length;
            for (var i = 0; i < c; i++) {
                var pos = q[i].indexOf('=');
                if (-1 == pos) continue;
                p[q[i].substr(0, pos).replace(/[^a-zA-Z0-9_]/g, '')] = unescape(q[i].substr(pos + 1));
            }

            return p;
        };

        var hash = location.href.toString().indexOf('#');
        if (hash < 0) hash = '';
        else {
            hash = location.href.toString().substring(hash, location.href.toString().length);
        }
        return {
            search: _myDecode(location.search.substr(1)),
            hash: _myDecode(hash)
        };
    },
};
/**
 * 请求本地存储
 * 避免操作的紊乱
 * @param Function fn 回调函数，它的参数是cache对象
 */
G.util.localShare = (function () {
    // 事件队列
    var _queue = G.createFnQueue(),
        _scriptLoaded = 0,
        _localCache = false;

    return function (fn) {
        _queue.add(fn);

        if (_scriptLoaded == 2 && _localCache) { // 加载已完成
            _queue.exec(_localCache);
            return;
        }

        if (_scriptLoaded == 1) { // 加载中
            return;
        }

        _scriptLoaded = 1;

        var ver = '1.1';
        $.ajax({
            dataType: 'script',
            crossDomain: true,
            cache: true,
            scriptCharset: 'gb2312',
            success: function () {
                G.app.localShare(function () {
                    _scriptLoaded = 2;
                    _localCache = this,
                        _queue.exec(_localCache);
                });
            }
        });
    };
})();

G.util.ping = {
    VISIT_INFO_KEY: 'vinfo',
    _visMap: ['lastVisit'],
    _performance: false,

    getVisitInfo: function () {
        var self = G.util.ping,
            visitInfo = G.util.cookie.get(self.VISIT_INFO_KEY),
            ret = {};

        visitInfo = visitInfo.split(',');
        $.each(self._visMap, function (k, v) {
            ret[v] = visitInfo[k] || '';
        });

        return ret;
    },

    setVisitInfo: function (key, val) {
        var self = G.util.ping,
            visitInfo = self.getVisitInfo(),
            p = {},
            r = [];

        if (arguments.length < 2) {
            p = key;
        }
        else {
            p[key] = val;
        }

        visitInfo = $.extend(visitInfo, key);
        $.each(self._visMap, function (k, v) {
            r[k] = visitInfo[v] || '';
        });

        G.util.cookie.add(self.VISIT_INFO_KEY, r.join(','), '/', 24 * 3600 * 365, '.' + G.domain);
    },
};
(function (G, $, undefined) {
    function tip(opt) {
        var instanceOf = function (o, type) {
            return (o && o.hasOwnProperty && (o instanceof type));
        };
        if (!(instanceOf(this, tip))) {
            return new tip(opt);
        }
        opt = jQuery.extend({}, {
            "position": "rightBottom",  // 提示tip相对于target的位置, 可选：'leftTop','rightTop','rightBottom','leftBottom'
            "distance": 20,  //尖角相对于tip顶点的距离
            "width": "120",
            "html": "",	//提示信息
            "target": null,	//tip相对停靠的节点, 类型： selector
            "buttons": null,	//tip中的按钮文字, 如 ['确定', '取消']
            "group": null,		//tip所属的组，当设定了这个参数，属于同一组的tip将在document中最多显示一个
            "className": "global_tip",	//tip最外层 节点的样式
            "time": null // time毫秒后自动关闭, 当存在按钮时，该参数无效
            //  "click_1" : function(){}	//点击第n个按钮时的回调函数, 从1开始
        }, opt || {});

        var self = this, target = $(opt.target), instance = target.data('tipInstnace');
        if (instance)
            instance.close();

        //属于同一组的tip只显示一个
        tip.instance = tip.instance || [];
        if (opt.group) {
            for (var i = 0, len = tip.instance.length; i < len; i++) {
                if (tip.instance[i].opt.group === opt.group) {
                    tip.instance[i].close();
                }
            }
        }
        ;

        var showButtons = (opt.buttons && !$.isArray(opt.buttons) ) || ($.isArray(opt.buttons) && opt.buttons.length > 0 );
        this.element = $('<div class="' + opt.className + '"><div class="content">' + opt.html + '</div>' + ( showButtons ? '<div class="buttons"></div>' : '') + '<span class="arrow">◆<span class="inner">◆</span></span></div>').css('width', opt.width);
        this.opt = opt;
        this.opt.id = new Date().getTime();

        //展现按钮
        if (showButtons) {
            var str = $.map($.isArray(opt.buttons) ? opt.buttons : [opt.buttons], function (value, index) {
                return '<a href="#" onclick="return false" class="' + ( index == 0 ? 'btn_strong' : 'btn_common' ) + '">' + value + '</a>';
            }).join('');
            var buttons = this.element.find('.buttons');
            buttons.append(str);
            buttons.find('a').each(function (index) {
                $(this).click(function () {
                    if (self.element.triggerHandler('click_' + ( index + 1 )) !== false)
                        self.close();
                });
            }).first().focus();
        }
        this.element.appendTo(document.body);

        //time毫秒后自动关闭
        if (!showButtons && opt.time) {
            this.timer = setTimeout(function () {
                self.close();
            }, parseInt(opt.time, 10));
        }

        //确定尖角的位置
        var arrowCss = {}, innerCss = {}, distance = parseInt(opt.distance, 10);
        var sizeTop = $.browser.mozilla ? 12 : ($.browser.webkit ? 12 : 13)
        var sizeBottom = $.browser.mozilla ? 10 : ($.browser.webkit ? 10 : 10)
        switch (opt.position) {
            case "leftTop" :
                arrowCss = {bottom: -1 * sizeTop, right: distance};
                innerCss = {top: -1};
                break;
            case "rightTop" :
                arrowCss = {left: distance, bottom: -1 * sizeTop};
                innerCss = {top: -1};
                break;
            case "leftBottom" :
                arrowCss = {top: -1 * sizeBottom, right: distance};
                innerCss = {top: 1}
                break;
            default :
                arrowCss = {top: -1 * sizeBottom, left: distance};
                innerCss = {top: 1};
                break;
        }

        var arrow = $(".arrow", this.element);
        arrow.css(arrowCss);
        $(".inner", this.element).css(innerCss);

        //确定整个tip的位置
        var arrowOffset = arrow.offset(), targetOffset = target.offset(), point1, point2;
        switch (opt.position) {
            case "leftTop":
            case "rightTop":
                point1 = {
                    x: parseInt(arrowOffset.left, 10) + parseInt(arrow.width(), 10) / 2,
                    y: parseInt(arrowOffset.top, 10) + parseInt(arrow.height(), 10)
                };

                point2 = {
                    x: parseInt(targetOffset.left, 10) + parseInt(target.width(), 10) / 2,
                    y: parseInt(targetOffset.top, 10)
                }
                break;
            default:
                point1 = {
                    x: parseInt(arrowOffset.left, 10) + parseInt(arrow.width(), 10) / 2,
                    y: parseInt(arrowOffset.top, 10)
                };

                point2 = {
                    x: parseInt(targetOffset.left, 10) + parseInt(target.width(), 10) / 2,
                    y: parseInt(targetOffset.top, 10) + parseInt(target.height(), 10)
                }
                break;
        }
        var pos = this.element.position();
        this.element.css({
            "left": parseInt(pos.left) - point1.x + point2.x,
            "top": parseInt(pos.top) - point1.y + point2.y
        });

        var self = this;
        self._close = function () {
            self && self.close();
        };
        $(window).bind('resize', self._close);

        tip.instance.push(this);
        target.data('tipInstnace', this);

        //通过形参绑定事件
        for (var name in opt) {
            if (/^click_\d$/.test(name.toString())) {
                this.bind(name, opt[name]);
            }
        }
    };

    $.extend(tip.prototype, {
        //绑定按钮事件
        bind: function () {
            this.element.bind.apply(this.element, $.makeArray(arguments));
        },

        //关闭tip
        close: function () {
            clearTimeout(this.timer);
            $(window).unbind('resize', self._close);
            this.element.data('tipInstnace', null);
            for (var i = 0, len = tip.instance.length; i < len; i++) {
                if (tip.instance[i].opt.id == this.opt.id) {
                    tip.instance.splice(i, 1);
                    break;
                }
            }
            this.element.remove();
        },

        //tip中的按钮
        getButtons: function () {
            return this.element.find(".buttons>a");
        },

        //tip最外层dom(jquery对象)
        getElement: function () {
            return this.element;
        },

        //tip是否显示
        isShow: function () {
            return this.element[0].style.display !== 'none'
        },

        //显示tip
        show: function () {
            this.element[0].style.display = 'block';
        },

        //隐藏tip
        hide: function () {
            this.element[0].style.display = 'none';
        }
    });
    G.ui.arrowTip = tip;
})(G, jQuery); 
